package httpClientUtil;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author chenzy
 * @Date 2020/8/17 15:40
 * @Version 1.0
 * @Description http 请求工具类：包含get post请求等等
 */
@Component
public class HttpUtil {

    private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
    private static Integer connectTimeout = 300000;// 30秒超时
    private static Integer socketTimeout = 400000;// 40秒超时


    private CloseableHttpClient httpClient;
    private static RequestConfig requestConfig = null;

    static {
        // 设置请求和传输超时时间
        requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
    }


    /**
     * 参数案例
     */
    public void params() {
        Header[] headers = {
                new BasicHeader("Content-Type", "application/json;charset=UTF-8")
                , new BasicHeader("method", "POST")
        };

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("client_id", "TD8246a8"));
    }


    /**
     * 获取单列模式 : CloseableHttpClient
     *
     * @return
     */
    public CloseableHttpClient getHttpInstance() throws Exception {
        if (httpClient == null) {
            synchronized (HttpUtil.class) {
                if (httpClient == null) {
                    logger.info("=== === 获取单列模式 : CloseableHttpClient！");
                    httpClient = HttpClientBuilder.create().build();
                }
            }
        }
        return httpClient;
    }


    /**
     * http post请求方法，返回json字符串
     *
     * @param url
     * @param params
     * @param headers 默认"application/x-www-form-urlencoded"
     * @return
     * @throws Exception
     */
    public String requestPost(String url, List<NameValuePair> params, Header[] headers) throws Exception {
        HttpPost httppost = new HttpPost(url);
        try {
            httppost.setConfig(requestConfig);
            if (null != params) {
                httppost.setEntity(new UrlEncodedFormEntity(params));
            }

            String res = postResponseStr(httppost, headers);
            return res;
        } catch (IOException e) {
            logger.error("=== === post请求提交异常:" + url, e);
        } finally {
            logger.info("=== === post请求完成关闭连接！");
            httppost.releaseConnection();
        }
        return null;
    }

    /**
     * http post请求方法，返回json字符串
     *
     * @param url
     * @param jsonDataStr
     * @param headers
     * @return
     * @throws Exception
     */
    public String requestPost(String url, String jsonDataStr, Header[] headers) throws Exception {
        HttpPost httppost = new HttpPost(url);
        try {
            httppost.setConfig(requestConfig);
            if (jsonDataStr != null) {
                StringEntity stringEntity = new StringEntity(jsonDataStr);
                stringEntity.setContentEncoding("UTF-8");
                httppost.setEntity(stringEntity);
            }

            String res = postResponseStr(httppost, headers);
            return res;
        } catch (IOException e) {
            logger.error("=== === post请求提交异常:" + url, e);
        } finally {
            logger.info("=== === post请求完成关闭连接！");
            httppost.releaseConnection();
        }
        return null;
    }


    /**
     * post请求，参数JSON字符串，返回 JSONObject
     *
     * @param url
     * @param jsonDataStr
     * @param headers
     * @return
     * @throws Exception
     */
    public JSONObject postToJSONObj(String url, String jsonDataStr, Header[] headers) throws Exception {
        String result = post(url, jsonDataStr, headers);
        if (result == null) {
            return null;
        }
        return JSONObject.parseObject(result);
    }

    /**
     * post请求，参数 List<NameValuePair>，返回 JSONObject
     *
     * @param url
     * @param params
     * @param headers
     * @return
     * @throws Exception
     */
    public JSONObject postToJSONObj(String url, List<NameValuePair> params, Header[] headers) throws Exception {
        String result = post(url, params, headers);
        if (result == null) {
            return null;
        }
        return JSONObject.parseObject(result);
    }

    /**
     * post请求，参数JSON字符串，返回 String
     *
     * @param url
     * @param jsonDataStr
     * @return
     */
    public String post(String url, String jsonDataStr, Header[] headers) throws Exception {
        String result = requestPost(url, jsonDataStr, headers);
        return result;
    }


    /**
     * post请求，参数List<NameValuePair>字符串，返回 String
     *
     * @param url
     * @param params
     * @return
     */
    public String post(String url, List<NameValuePair> params, Header[] headers) throws Exception {
        String result = requestPost(url, params, headers);
        return result;
    }


    /**
     * post返回url请求的响应response
     *
     * @param post
     * @return
     * @throws Exception
     */
    public CloseableHttpResponse postReqHttpResponse(HttpPost post) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        return httpClient.execute(post);
    }


    /**
     * post请求
     *
     * @param httppost
     * @param headers
     * @return
     * @throws Exception
     */
    public String postResponseStr(HttpPost httppost, Header[] headers) throws Exception {
        if (null != headers) {
            httppost.setHeaders(headers);
        }

        CloseableHttpResponse response = getHttpInstance().execute(httppost);
        HttpEntity entity = response.getEntity();
        // 返回的有可能是加密的字符串
        String jsonStr = EntityUtils.toString(entity, "UTF-8");

        //响应操作
        if (jsonStr != null) {
            logger.info("=== === post 请求完成成功！" + jsonStr);
            return jsonStr;
        }
        return null;
    }

    /**
     * http get请求方法，返回json字符串
     *
     * @param urlWithParams
     * @param headers
     * @return
     * @throws Exception
     */
    public String requestGet(String urlWithParams, Header[] headers) throws Exception {
        HttpGet httpget = new HttpGet(urlWithParams);
        try {
            httpget.setConfig(requestConfig);

            if (null != headers) {
                httpget.setHeaders(headers);
            }
            CloseableHttpResponse response = getHttpInstance().execute(httpget);

            HttpEntity entity = response.getEntity();
            String jsonStr = EntityUtils.toString(entity, "utf-8");

            if (jsonStr != null) {
                logger.info("=== === get 请求完成成功！" + jsonStr);
                return jsonStr;
            }
        } catch (IOException e) {
            logger.error("=== === get 请求提交异常:" + urlWithParams, e);
        } finally {
            logger.info("=== === get 请求完成关闭连接！");
            httpget.releaseConnection();
        }
        return null;
    }

    /**
     * Get请求数据转成JSONObject
     *
     * @param urlWithParams
     * @param headers
     * @return
     * @throws Exception
     */
    public JSONObject requestGetToJSONObj(String urlWithParams, Header[] headers) throws Exception {
        String result = requestGet(urlWithParams, headers);
        if (result == null) {
            return null;
        }
        return JSONObject.parseObject(result);
    }


    /**
     * get返回url请求的响应response
     *
     * @param url
     * @return
     */
    public CloseableHttpResponse getReqHttpResponse(String url) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpget = new HttpGet(url);
        return httpClient.execute(httpget);
    }
}
